# This file is part of Cantera. See License.txt in the top-level directory or
# at https://cantera.org/license.txt for license and copyright information.

from collections.abc import Callable
from pathlib import Path
from typing import Any, Literal, ParamSpec, TypeAlias, TypeVar

from pint import Quantity
from pint.registry import ApplicationRegistry

from .._types import Array, CompositionLike
from .._utils import CanteraError as CanteraError

__all__: list[str] = [
    "Q_",
    "CanteraError",
    "CarbonDioxide",
    "Heptane",
    "Hfc134a",
    "Hydrogen",
    "Methane",
    "Nitrogen",
    "Oxygen",
    "PureFluid",
    "Solution",
    "Water",
    "units",
]

# Define some helpful type aliases
_Quantity: TypeAlias = Quantity[float]  # type: ignore[type-arg]
_PropertyPairSetter: TypeAlias = tuple[_Quantity | None, _Quantity | None]
_StateSetter: TypeAlias = tuple[
    _Quantity | None, _Quantity | None, _Quantity | CompositionLike
]

units: ApplicationRegistry
Q_: type[Quantity[float]]  # type: ignore[type-arg]

_P = ParamSpec("_P")
_T = TypeVar("_T")
def copy_doc(method: Callable[_P, _T]) -> Callable[_P, _T]: ...

class Solution:
    def __init__(
        self, infile: Path | str = "", name: str = "", *, yaml: str | None = None
    ) -> None: ...
    @copy_doc
    def report(self, *args: Any, **kwargs: Any) -> str: ...
    def __call__(self, *args: Any, **kwargs: Any) -> None: ...
    @property
    def basis_units(self) -> Literal["kg", "kmol"]: ...
    @property
    @copy_doc
    def X(self) -> _Quantity: ...
    @X.setter
    def X(self, value: _Quantity | CompositionLike | None) -> None: ...
    @property
    @copy_doc
    def Y(self) -> _Quantity: ...
    @Y.setter
    def Y(self, value: _Quantity | CompositionLike | None) -> None: ...
    @property
    @copy_doc
    def density_mass(self) -> _Quantity: ...
    @property
    @copy_doc
    def density_mole(self) -> _Quantity: ...
    @property
    @copy_doc
    def enthalpy_mass(self) -> _Quantity: ...
    @property
    @copy_doc
    def enthalpy_mole(self) -> _Quantity: ...
    @property
    @copy_doc
    def entropy_mass(self) -> _Quantity: ...
    @property
    @copy_doc
    def entropy_mole(self) -> _Quantity: ...
    @property
    @copy_doc
    def int_energy_mass(self) -> _Quantity: ...
    @property
    @copy_doc
    def int_energy_mole(self) -> _Quantity: ...
    @property
    @copy_doc
    def volume_mass(self) -> _Quantity: ...
    @property
    @copy_doc
    def volume_mole(self) -> _Quantity: ...
    @property
    @copy_doc
    def gibbs_mass(self) -> _Quantity: ...
    @property
    @copy_doc
    def gibbs_mole(self) -> _Quantity: ...
    @property
    @copy_doc
    def cp_mass(self) -> _Quantity: ...
    @property
    @copy_doc
    def cp_mole(self) -> _Quantity: ...
    @property
    @copy_doc
    def cv_mass(self) -> _Quantity: ...
    @property
    @copy_doc
    def cv_mole(self) -> _Quantity: ...
    @property
    @copy_doc
    def P(self) -> _Quantity: ...
    @property
    @copy_doc
    def P_sat(self) -> _Quantity: ...
    @property
    @copy_doc
    def T(self) -> _Quantity: ...
    @property
    @copy_doc
    def T_sat(self) -> _Quantity: ...
    @property
    @copy_doc
    def atomic_weight(self) -> _Quantity: ...
    @property
    @copy_doc
    def chemical_potentials(self) -> _Quantity: ...
    @property
    @copy_doc
    def concentrations(self) -> _Quantity: ...
    @property
    @copy_doc
    def critical_pressure(self) -> _Quantity: ...
    @property
    @copy_doc
    def critical_temperature(self) -> _Quantity: ...
    @property
    @copy_doc
    def critical_density(self) -> _Quantity: ...
    @property
    @copy_doc
    def electric_potential(self) -> _Quantity: ...
    @property
    @copy_doc
    def electrochemical_potentials(self) -> _Quantity: ...
    @property
    @copy_doc
    def isothermal_compressibility(self) -> _Quantity: ...
    @property
    @copy_doc
    def sound_speed(self) -> _Quantity: ...
    @property
    @copy_doc
    def max_temp(self) -> _Quantity: ...
    @property
    @copy_doc
    def mean_molecular_weight(self) -> _Quantity: ...
    @property
    @copy_doc
    def min_temp(self) -> _Quantity: ...
    @property
    @copy_doc
    def molecular_weights(self) -> _Quantity: ...
    @property
    @copy_doc
    def partial_molar_cp(self) -> _Quantity: ...
    @property
    @copy_doc
    def partial_molar_enthalpies(self) -> _Quantity: ...
    @property
    @copy_doc
    def partial_molar_entropies(self) -> _Quantity: ...
    @property
    @copy_doc
    def partial_molar_int_energies(self) -> _Quantity: ...
    @property
    @copy_doc
    def partial_molar_volumes(self) -> _Quantity: ...
    @property
    @copy_doc
    def reference_pressure(self) -> _Quantity: ...
    @property
    @copy_doc
    def thermal_expansion_coeff(self) -> _Quantity: ...
    @property
    @copy_doc
    def cp(self) -> _Quantity: ...
    @property
    @copy_doc
    def cv(self) -> _Quantity: ...
    @property
    @copy_doc
    def density(self) -> _Quantity: ...
    @property
    @copy_doc
    def h(self) -> _Quantity: ...
    @property
    @copy_doc
    def s(self) -> _Quantity: ...
    @property
    @copy_doc
    def g(self) -> _Quantity: ...
    @property
    @copy_doc
    def u(self) -> _Quantity: ...
    @property
    @copy_doc
    def v(self) -> _Quantity: ...
    @property
    @copy_doc
    def TP(self) -> tuple[_Quantity, _Quantity]: ...
    @TP.setter
    def TP(self, value: _PropertyPairSetter) -> None: ...
    @property
    @copy_doc
    def DP(self) -> tuple[_Quantity, _Quantity]: ...
    @DP.setter
    def DP(self, value: _PropertyPairSetter) -> None: ...
    @property
    @copy_doc
    def HP(self) -> tuple[_Quantity, _Quantity]: ...
    @HP.setter
    def HP(self, value: _PropertyPairSetter) -> None: ...
    @property
    @copy_doc
    def SP(self) -> tuple[_Quantity, _Quantity]: ...
    @SP.setter
    def SP(self, value: _PropertyPairSetter) -> None: ...
    @property
    @copy_doc
    def SV(self) -> tuple[_Quantity, _Quantity]: ...
    @SV.setter
    def SV(self, value: _PropertyPairSetter) -> None: ...
    @property
    @copy_doc
    def TD(self) -> tuple[_Quantity, _Quantity]: ...
    @TD.setter
    def TD(self, value: _PropertyPairSetter) -> None: ...
    @property
    @copy_doc
    def UV(self) -> tuple[_Quantity, _Quantity]: ...
    @UV.setter
    def UV(self, value: _PropertyPairSetter) -> None: ...
    @property
    @copy_doc
    def TPX(self) -> tuple[_Quantity, _Quantity, _Quantity]: ...
    @TPX.setter
    def TPX(self, value: _StateSetter) -> None: ...
    @property
    @copy_doc
    def TPY(self) -> tuple[_Quantity, _Quantity, _Quantity]: ...
    @TPY.setter
    def TPY(self, value: _StateSetter) -> None: ...
    @property
    @copy_doc
    def DPX(self) -> tuple[_Quantity, _Quantity, _Quantity]: ...
    @DPX.setter
    def DPX(self, value: _StateSetter) -> None: ...
    @property
    @copy_doc
    def DPY(self) -> tuple[_Quantity, _Quantity, _Quantity]: ...
    @DPY.setter
    def DPY(self, value: _StateSetter) -> None: ...
    @property
    @copy_doc
    def HPX(self) -> tuple[_Quantity, _Quantity, _Quantity]: ...
    @HPX.setter
    def HPX(self, value: _StateSetter) -> None: ...
    @property
    @copy_doc
    def HPY(self) -> tuple[_Quantity, _Quantity, _Quantity]: ...
    @HPY.setter
    def HPY(self, value: _StateSetter) -> None: ...
    @property
    @copy_doc
    def SPX(self) -> tuple[_Quantity, _Quantity, _Quantity]: ...
    @SPX.setter
    def SPX(self, value: _StateSetter) -> None: ...
    @property
    @copy_doc
    def SPY(self) -> tuple[_Quantity, _Quantity, _Quantity]: ...
    @SPY.setter
    def SPY(self, value: _StateSetter) -> None: ...
    @property
    @copy_doc
    def SVX(self) -> tuple[_Quantity, _Quantity, _Quantity]: ...
    @SVX.setter
    def SVX(self, value: _StateSetter) -> None: ...
    @property
    @copy_doc
    def SVY(self) -> tuple[_Quantity, _Quantity, _Quantity]: ...
    @SVY.setter
    def SVY(self, value: _StateSetter) -> None: ...
    @property
    @copy_doc
    def TDX(self) -> tuple[_Quantity, _Quantity, _Quantity]: ...
    @TDX.setter
    def TDX(self, value: _StateSetter) -> None: ...
    @property
    @copy_doc
    def TDY(self) -> tuple[_Quantity, _Quantity, _Quantity]: ...
    @TDY.setter
    def TDY(self, value: _StateSetter) -> None: ...
    @property
    @copy_doc
    def UVX(self) -> tuple[_Quantity, _Quantity, _Quantity]: ...
    @UVX.setter
    def UVX(self, value: _StateSetter) -> None: ...
    @property
    @copy_doc
    def UVY(self) -> tuple[_Quantity, _Quantity, _Quantity]: ...
    @UVY.setter
    def UVY(self, value: _StateSetter) -> None: ...

class PureFluid:
    def __init__(
        self,
        infile: Path | str,
        name: str = "",
        *,
        yaml: str | None = None,
        **kwargs: Any,
    ) -> None: ...
    @copy_doc
    def report(self, *args: Any, **kwargs: Any) -> str: ...
    def __call__(self, *args: Any, **kwargs: Any) -> None: ...
    @property
    def basis_units(self) -> Literal["kg", "kmol"]: ...
    @property
    @copy_doc
    def X(self) -> _Quantity: ...
    @X.setter
    def X(self, value: _Quantity | CompositionLike | None) -> None: ...
    @property
    @copy_doc
    def Y(self) -> _Quantity: ...
    @Y.setter
    def Y(self, value: _Quantity | CompositionLike | None) -> None: ...
    @property
    @copy_doc
    def Q(self) -> _Quantity: ...
    @Q.setter
    def Q(self, value: _Quantity | None) -> None: ...
    @property
    @copy_doc
    def density_mass(self) -> _Quantity: ...
    @property
    @copy_doc
    def density_mole(self) -> _Quantity: ...
    @property
    @copy_doc
    def enthalpy_mass(self) -> _Quantity: ...
    @property
    @copy_doc
    def enthalpy_mole(self) -> _Quantity: ...
    @property
    @copy_doc
    def entropy_mass(self) -> _Quantity: ...
    @property
    @copy_doc
    def entropy_mole(self) -> _Quantity: ...
    @property
    @copy_doc
    def int_energy_mass(self) -> _Quantity: ...
    @property
    @copy_doc
    def int_energy_mole(self) -> _Quantity: ...
    @property
    @copy_doc
    def volume_mass(self) -> _Quantity: ...
    @property
    @copy_doc
    def volume_mole(self) -> _Quantity: ...
    @property
    @copy_doc
    def gibbs_mass(self) -> _Quantity: ...
    @property
    @copy_doc
    def gibbs_mole(self) -> _Quantity: ...
    @property
    @copy_doc
    def cp_mass(self) -> _Quantity: ...
    @property
    @copy_doc
    def cp_mole(self) -> _Quantity: ...
    @property
    @copy_doc
    def cv_mass(self) -> _Quantity: ...
    @property
    @copy_doc
    def cv_mole(self) -> _Quantity: ...
    @property
    @copy_doc
    def P(self) -> _Quantity: ...
    @property
    @copy_doc
    def P_sat(self) -> _Quantity: ...
    @property
    @copy_doc
    def T(self) -> _Quantity: ...
    @property
    @copy_doc
    def T_sat(self) -> _Quantity: ...
    @property
    @copy_doc
    def atomic_weight(self) -> _Quantity: ...
    @property
    @copy_doc
    def chemical_potentials(self) -> _Quantity: ...
    @property
    @copy_doc
    def concentrations(self) -> _Quantity: ...
    @property
    @copy_doc
    def critical_pressure(self) -> _Quantity: ...
    @property
    @copy_doc
    def critical_temperature(self) -> _Quantity: ...
    @property
    @copy_doc
    def critical_density(self) -> _Quantity: ...
    @property
    @copy_doc
    def electric_potential(self) -> _Quantity: ...
    @property
    @copy_doc
    def electrochemical_potentials(self) -> _Quantity: ...
    @property
    @copy_doc
    def isothermal_compressibility(self) -> _Quantity: ...
    @property
    @copy_doc
    def sound_speed(self) -> _Quantity: ...
    @property
    @copy_doc
    def max_temp(self) -> _Quantity: ...
    @property
    @copy_doc
    def mean_molecular_weight(self) -> _Quantity: ...
    @property
    @copy_doc
    def min_temp(self) -> _Quantity: ...
    @property
    @copy_doc
    def molecular_weights(self) -> _Quantity: ...
    @property
    @copy_doc
    def partial_molar_cp(self) -> _Quantity: ...
    @property
    @copy_doc
    def partial_molar_enthalpies(self) -> _Quantity: ...
    @property
    @copy_doc
    def partial_molar_entropies(self) -> _Quantity: ...
    @property
    @copy_doc
    def partial_molar_int_energies(self) -> _Quantity: ...
    @property
    @copy_doc
    def partial_molar_volumes(self) -> _Quantity: ...
    @property
    @copy_doc
    def reference_pressure(self) -> _Quantity: ...
    @property
    @copy_doc
    def thermal_expansion_coeff(self) -> _Quantity: ...
    @property
    @copy_doc
    def cp(self) -> _Quantity: ...
    @property
    @copy_doc
    def cv(self) -> _Quantity: ...
    @property
    @copy_doc
    def density(self) -> _Quantity: ...
    @property
    @copy_doc
    def h(self) -> _Quantity: ...
    @property
    @copy_doc
    def s(self) -> _Quantity: ...
    @property
    @copy_doc
    def g(self) -> _Quantity: ...
    @property
    @copy_doc
    def u(self) -> _Quantity: ...
    @property
    @copy_doc
    def v(self) -> _Quantity: ...
    @property
    @copy_doc
    def TP(self) -> tuple[_Quantity, _Quantity]: ...
    @TP.setter
    def TP(self, value: _PropertyPairSetter) -> None: ...
    @property
    @copy_doc
    def DP(self) -> tuple[_Quantity, _Quantity]: ...
    @DP.setter
    def DP(self, value: _PropertyPairSetter) -> None: ...
    @property
    @copy_doc
    def HP(self) -> tuple[_Quantity, _Quantity]: ...
    @HP.setter
    def HP(self, value: _PropertyPairSetter) -> None: ...
    @property
    @copy_doc
    def SP(self) -> tuple[_Quantity, _Quantity]: ...
    @SP.setter
    def SP(self, value: _PropertyPairSetter) -> None: ...
    @property
    @copy_doc
    def SV(self) -> tuple[_Quantity, _Quantity]: ...
    @SV.setter
    def SV(self, value: _PropertyPairSetter) -> None: ...
    @property
    @copy_doc
    def TD(self) -> tuple[_Quantity, _Quantity]: ...
    @TD.setter
    def TD(self, value: _PropertyPairSetter) -> None: ...
    @property
    @copy_doc
    def UV(self) -> tuple[_Quantity, _Quantity]: ...
    @UV.setter
    def UV(self, value: _PropertyPairSetter) -> None: ...
    @property
    @copy_doc
    def TPX(self) -> tuple[_Quantity, _Quantity, _Quantity]: ...
    @TPX.setter
    def TPX(self, value: _StateSetter) -> None: ...
    @property
    @copy_doc
    def TPY(self) -> tuple[_Quantity, _Quantity, _Quantity]: ...
    @TPY.setter
    def TPY(self, value: _StateSetter) -> None: ...
    @property
    @copy_doc
    def DPX(self) -> tuple[_Quantity, _Quantity, _Quantity]: ...
    @DPX.setter
    def DPX(self, value: _StateSetter) -> None: ...
    @property
    @copy_doc
    def DPY(self) -> tuple[_Quantity, _Quantity, _Quantity]: ...
    @DPY.setter
    def DPY(self, value: _StateSetter) -> None: ...
    @property
    @copy_doc
    def HPX(self) -> tuple[_Quantity, _Quantity, _Quantity]: ...
    @HPX.setter
    def HPX(self, value: _StateSetter) -> None: ...
    @property
    @copy_doc
    def HPY(self) -> tuple[_Quantity, _Quantity, _Quantity]: ...
    @HPY.setter
    def HPY(self, value: _StateSetter) -> None: ...
    @property
    @copy_doc
    def SPX(self) -> tuple[_Quantity, _Quantity, _Quantity]: ...
    @SPX.setter
    def SPX(self, value: _StateSetter) -> None: ...
    @property
    @copy_doc
    def SPY(self) -> tuple[_Quantity, _Quantity, _Quantity]: ...
    @SPY.setter
    def SPY(self, value: _StateSetter) -> None: ...
    @property
    @copy_doc
    def SVX(self) -> tuple[_Quantity, _Quantity, _Quantity]: ...
    @SVX.setter
    def SVX(self, value: _StateSetter) -> None: ...
    @property
    @copy_doc
    def SVY(self) -> tuple[_Quantity, _Quantity, _Quantity]: ...
    @SVY.setter
    def SVY(self, value: _StateSetter) -> None: ...
    @property
    @copy_doc
    def TDX(self) -> tuple[_Quantity, _Quantity, _Quantity]: ...
    @TDX.setter
    def TDX(self, value: _StateSetter) -> None: ...
    @property
    @copy_doc
    def TDY(self) -> tuple[_Quantity, _Quantity, _Quantity]: ...
    @TDY.setter
    def TDY(self, value: _StateSetter) -> None: ...
    @property
    @copy_doc
    def UVX(self) -> tuple[_Quantity, _Quantity, _Quantity]: ...
    @UVX.setter
    def UVX(self, value: _StateSetter) -> None: ...
    @property
    @copy_doc
    def UVY(self) -> tuple[_Quantity, _Quantity, _Quantity]: ...
    @UVY.setter
    def UVY(self, value: _StateSetter) -> None: ...
    @property
    @copy_doc
    def TPQ(self) -> tuple[_Quantity, _Quantity, _Quantity]: ...
    @TPQ.setter
    def TPQ(self, value: _StateSetter) -> None: ...
    @property
    @copy_doc
    def PQ(self) -> tuple[_Quantity, _Quantity]: ...
    @PQ.setter
    def PQ(self, value: _PropertyPairSetter) -> None: ...
    @property
    @copy_doc
    def TQ(self) -> tuple[_Quantity, _Quantity]: ...
    @TQ.setter
    def TQ(self, value: _PropertyPairSetter) -> None: ...
    @property
    @copy_doc
    def PV(self) -> tuple[_Quantity, _Quantity]: ...
    @PV.setter
    def PV(self, value: _PropertyPairSetter) -> None: ...
    @property
    @copy_doc
    def SH(self) -> tuple[_Quantity, _Quantity]: ...
    @SH.setter
    def SH(self, value: _PropertyPairSetter) -> None: ...
    @property
    @copy_doc
    def ST(self) -> tuple[_Quantity, _Quantity]: ...
    @ST.setter
    def ST(self, value: _PropertyPairSetter) -> None: ...
    @property
    @copy_doc
    def TH(self) -> tuple[_Quantity, _Quantity]: ...
    @TH.setter
    def TH(self, value: _PropertyPairSetter) -> None: ...
    @property
    @copy_doc
    def TV(self) -> tuple[_Quantity, _Quantity]: ...
    @TV.setter
    def TV(self, value: _PropertyPairSetter) -> None: ...
    @property
    @copy_doc
    def UP(self) -> tuple[_Quantity, _Quantity]: ...
    @UP.setter
    def UP(self, value: _PropertyPairSetter) -> None: ...
    @property
    @copy_doc
    def VH(self) -> tuple[_Quantity, _Quantity]: ...
    @VH.setter
    def VH(self, value: _PropertyPairSetter) -> None: ...
    @property
    @copy_doc
    def DPQ(self) -> tuple[_Quantity, _Quantity, _Quantity]: ...
    @property
    @copy_doc
    def HPQ(self) -> tuple[_Quantity, _Quantity, _Quantity]: ...
    @property
    @copy_doc
    def SPQ(self) -> tuple[_Quantity, _Quantity, _Quantity]: ...
    @property
    @copy_doc
    def SVQ(self) -> tuple[_Quantity, _Quantity, _Quantity]: ...
    @property
    @copy_doc
    def TDQ(self) -> tuple[_Quantity, _Quantity, _Quantity]: ...
    @property
    @copy_doc
    def UVQ(self) -> tuple[_Quantity, _Quantity, _Quantity]: ...

def Heptane() -> PureFluid: ...
def CarbonDioxide() -> PureFluid: ...
def Hfc134a() -> PureFluid: ...
def Hydrogen() -> PureFluid: ...
def Methane() -> PureFluid: ...
def Nitrogen() -> PureFluid: ...
def Oxygen() -> PureFluid: ...
def Water(backend: Literal["Reynolds", "IAPWS95"] = "Reynolds") -> PureFluid: ...
